﻿using AutoMapper;
using DFGK_WMS.Context;
using DFGK_WMS.IRepository;
using DFGK_WMS.Model.Models;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
using DFGK.WMS.Common.Extensions;
using DFGK_WMS.Repository.Service;
using NetTaste;
using DFGK_WMS.Model.Models.PDA;
using DFGK_WMS.Model.Enum;
using Microsoft.IdentityModel.Logging;
using Org.BouncyCastle.Bcpg;
using SqlSugar;
using DFGK_WMS.IRepository.IService;

namespace DFGK_WMS.Repository
{
    public class PDAStackingRepository : BaseRepository<TStackingStorage>, IPDAStackingRepository
    {
        public PDAStackingRepository(DFGK_DB context, IMapper mapper) : base(context, mapper)
        {
        }

        /// <summary>
        /// 查询托盘表数据
        /// </summary>
        /// <param name="PalletBarcode"></param>
        /// <returns></returns>
        public TPallet GetPallet(TPalletCriteriaModel item)
        {
            var list = Context.TPallets
                 .Where(x => x.PalletBarcode == item.PalletBarcode).FirstOrDefault();
            return list;
        }

        /// <summary>
        /// 查询字典项数据
        /// </summary>
        /// <param name="typeCode"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<TDictItem> GetDictItemListByTypeCode(string ItemCode)
        {
            if (ItemCode == null)
            {
                return null;
            }

            var list = Context.TDictItems
                .Where(x => x.TypeCode == ItemCode)
                .ToList();
            if (list.Count < 0)
            {
                return null;
            }
            return list;
        }

        /// <summary>
        /// 查询入库垛信息
        /// </summary>
        /// <param name="criteria"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<TStackingStorage> GetStackingStorageList(TStackingStorageCriteriaModel criteria)
        {
            var query = Context.TStackingStorages.AsQueryable();

            if (criteria.WarehouseCode != null)
            {
                query = query.Where(x => x.WarehouseCode == criteria.WarehouseCode);
            }
            if (criteria.AreaCode != null)
            {
                query = query.Where(x => x.AreaCode == criteria.AreaCode);
            }
            if (criteria.RelatedOrderDetailId != null)
            {
                query = query.Where(x => x.RelatedOrderDetailId == criteria.RelatedOrderDetailId);
            }
            if (criteria.PalletBarcode != null)
            {
                query = query.Where(x => x.PalletBarcode == criteria.PalletBarcode);
            }
            if (criteria.MaterialId != null)
            {
                query = query.Where(x => x.MaterialId == criteria.MaterialId);
            }
            if (criteria.LogicalPartCode != null)
            {
                query = query.Where(x => x.LogicalPartCode == criteria.LogicalPartCode);
            }


            return query.ToList();
        }

        /// <summary>
        /// 根据垛条码查询库存信息
        /// </summary>
        /// <param name="PalletBarcode"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<TInventory> GetInventoryByPalletBarcode(string PalletBarcode)
        {
            var list = Context.TInventories
                .Where(x => x.PalletBarcode == PalletBarcode)
                .ToList();

            return list;
        }

        /// <summary>
        /// 查询入库申请单信息
        /// </summary>
        /// <param name="criteria"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public TReceivingOrderDetail GetReceivingOrderDetail(int? OrderDetailId)
        {
            if (OrderDetailId == null || OrderDetailId <= 0)
            {
                return null;
            }
            var query = Context.TReceivingOrderDetails.FirstOrDefault(x => x.Id == OrderDetailId);

            return query;

        }

        /// <summary>
        /// 查询物料信息
        /// </summary>
        /// <param name="MaterialCode"></param>
        /// <returns></returns>
        public TMaterial GetMaterial(string? MaterialCode)
        {
            if (MaterialCode == null)
            {
                return null;
            }
            var query = Context.TMaterial.FirstOrDefault(x => x.Code == MaterialCode);

            return query;
        }

        /// <summary>
        /// 查询入库单明细数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        private TReceivingOrderDetail GetTReceivingOrderDetail(int id)
        {
            var list = Context.TReceivingOrderDetails
                .Where(x => x.Id == id).ToList();

            return list.FirstOrDefault();
        }


        /// <summary>
        /// 获取入库垛信息
        /// </summary>
        /// <param name="criteria"></param>
        /// <returns></returns>
        public TStackingStorage GetStackingStorage(StackingStorageCriteriaModel criteria)
        {
            var list = Context.TStackingStorages.AsQueryable();
            if (criteria == null)
            {
                return null;
            }
            if (criteria.WarehouseCode != null)
            {
                list = list.Where(x => x.WarehouseCode == criteria.WarehouseCode);
            }
            if (criteria.PalletBarcode != null)
            {
                list = list.Where(x => x.PalletBarcode == criteria.PalletBarcode);
            }

            return list.FirstOrDefault();

        } 

        /// <summary>
        /// 查询托盘是否存在
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public TPallet GetPallet(PalletCriteriaModel item)
        {
            var list = Context.TPallets.AsQueryable();
            if (item == null)
            {
                return null;
            }
            if (item.PalletBarcode != null)
            {
                list = list.Where(x => x.PalletBarcode == item.PalletBarcode);
            }
            if (item.WarehouseCode != null)
            {
                list = list.Where(x => x.WarehouseCode == item.WarehouseCode);
            }

            return list.FirstOrDefault();
        }

        /// <summary>
        /// 入库垛表插入数据
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        private int InsertStackingStorage( TStackingStorage model)
        {
            using (var tran = Context.Database.BeginTransaction())
            {
                try
                {
                    Context.Add(model);
                    tran.Commit();
                    return 1;
                }
                catch
                {
                    tran.Rollback();
                    return 0;
                }

            }

        }


        /// <summary>
        /// 创建组垛
        /// </summary>
        /// <param name="palletBindModel"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool BuildCreateStackingStorage(Model.Models.PalletBindMaterialModel palletBindModel)
        {
            bool result = false;
            string palletBarcode = palletBindModel.PalletBarcode;
            List<string> palletBarcodeList = palletBarcode.StringToList();
            if (palletBarcodeList != null && palletBarcodeList.Count > 0)
            {
                palletBarcode = palletBarcodeList[0];
                palletBarcodeList.Remove(palletBarcode);
            }
            int OrderId = palletBindModel.MaterialPackageBindModel.OrderDetailId;
            var orderDetail = GetTReceivingOrderDetail(OrderId);
            decimal? materialNum = 0;
            materialNum = palletBindModel.MaterialPackageBindModel.Qty;
            using (var tran = Context.Database.BeginTransaction())
            {
                try
                {
                    int stackingId = 0;
                    string LogicPartCode = "";

                    var tackingStorage = GetStackingStorage(new StackingStorageCriteriaModel()
                    {
                        PalletBarcode = palletBarcode,
                        RelatedOrderDetailId = OrderId,
                        WarehouseCode = orderDetail.WarehouseCode,
                        Status = 1
                    });
                    if (tackingStorage != null && tackingStorage.Id > 0)
                    {
                        stackingId = tackingStorage.Id;
                    }
                    else
                    {
                        var pallet = GetPallet(new PalletCriteriaModel() { PalletBarcode = palletBarcode });
                        if (pallet is null || string.IsNullOrWhiteSpace(pallet.PalletBarcode))
                        {
                            tran.Rollback();
                            return false;
                        }
                        if (pallet.Type == (int)PalletTypeEnum.Pallet)
                        {
                            LogicPartCode = "TuoPan";
                        }
                        else if (pallet.Type == (int)PalletTypeEnum.Box64)
                        {
                            LogicPartCode = "Box6040";
                        }
                        else if (pallet.Type == (int)PalletTypeEnum.Box86)
                        {
                            LogicPartCode = "Box8060";
                        }
                        stackingId = InsertStackingStorage(new TStackingStorage
                        {
                            WarehouseName = orderDetail.WarehouseName,
                            WarehouseCode = orderDetail.WarehouseCode,
                            BillType = (int)orderDetail.BillType.GetValueOrDefault(),
                            RelatedOrderDetailId = OrderId,
                            Status = 1,
                            PalletBarcode = palletBarcode,
                            Qty = materialNum,
                            PackQty = 1,
                            AreaCode = "",
                            LogicalPartCode = LogicPartCode,
                            MaterialId = orderDetail.MaterialId,
                            MaterialCode = orderDetail.MaterialCode,
                            MaterialName = orderDetail.MaterialName,
                            MaterialKeyId = orderDetail.MaterialKeyId,
                            CreateUserId = orderDetail.CreateUserId,
                            CreateUserName = orderDetail.CreateUserName,
                            BatchNo = orderDetail.BatchNo,
                            CreateDate = DateTime.Now,
                            Fifodate = DateTime.Now
                        });
                    }
                    result = stackingId > 0;
                    if (!result)
                    {
                        tran.Rollback();
                        return false;
                    }

                    // 垛包装数据保存
                    if (palletBarcodeList != null && palletBarcodeList.Count > 0)
                    {

                        foreach (var itemPalletBarcode in palletBarcodeList)
                        {
                            var pallet = GetPallet(new PalletCriteriaModel()
                            {
                                PalletBarcode = itemPalletBarcode
                            });
                            if (pallet is null || string.IsNullOrWhiteSpace(pallet.PalletBarcode))
                            {
                                return false;
                            }
                            if (pallet.Type == (int)PalletTypeEnum.Pallet)
                            {
                                LogicPartCode = "TuoPan";
                            }
                            else if (pallet.Type == (int)PalletTypeEnum.Box64)
                            {
                                LogicPartCode = "Box6040";
                            }
                            else if (pallet.Type == (int)PalletTypeEnum.Box86)
                            {
                                LogicPartCode = "Box8060";
                            }
                            int chStackingId = InsertStackingStorage(new TStackingStorage
                            {
                                WarehouseName = orderDetail.WarehouseName,
                                WarehouseCode = orderDetail.WarehouseCode,
                                BillType = (int)orderDetail.BillType.GetValueOrDefault(),
                                RelatedOrderDetailId = OrderId,
                                Status = 1,
                                PalletBarcode = itemPalletBarcode,
                                Qty = materialNum,
                                PackQty = 1,
                                AreaCode = "",
                                LogicalPartCode = LogicPartCode,
                                MaterialId = orderDetail.MaterialId,
                                MaterialCode = orderDetail.MaterialCode,
                                MaterialName = orderDetail.MaterialName,
                                MaterialKeyId = orderDetail.MaterialKeyId,
                                CreateUserId = orderDetail.CreateUserId,
                                CreateUserName = orderDetail.CreateUserName,
                                BatchNo = orderDetail.BatchNo,
                                CreateDate = DateTime.Now,
                                Fifodate = DateTime.Now,
                                ParentPalletBarcode = palletBarcode
                            });
                            result = chStackingId > 0;
                            if (!result)
                            {
                                return false;
                            }
                        }
                    }


                }
                catch
                {
                    tran.Rollback();
                    return false;
                }
            }


            return true;
        }
    }
}
